package com.entrogy.timing;

import com.entrogy.bean.DeviceEntity;
import com.entrogy.bean.MachineEntity;
import com.entrogy.bean.PubCountEntity;
import com.entrogy.bean.SchoolThdidUrlEntity;
import com.entrogy.dao.MachineMapper;
import com.entrogy.dao.MessageMapper;
import com.entrogy.service.SchoolService;
import com.entrogy.utils.RedissonManager;
import com.entrogy.utils.SendUtils;
import com.entrogy.utils.THDio;
import com.entrogy.utils.constants.Constants;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName CreateScoreTableTiming
 * @Description 设备在线状态监测
 * @Author luoxingjiang
 * @Date 2020/01/06 0004 上午 9:50
 * @Version 1.0
 **/
@Component
public class DeviceDetectTiming {


    private static final Logger logger = LoggerFactory.getLogger(DeviceDetectTiming.class);

    @Autowired
    private SchoolService schoolService;

    @Autowired
    private MachineMapper machineMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private RedissonManager redissonManager;


    @Autowired
    private THDio thDio;

    @Scheduled(cron = "0 0 1 * * ?")// 每天的01:00:00执行
    private void insertDeviceOnlineStatus() {
        RLock lock = redissonManager.getRedisson().getLock(Constants.PAY_ORDER_IS_OUT_OF);
        boolean getLock = false;
        try {
            //todo 若任务执行时间过短，则有可能在等锁的过程中2个服务任务都会获取到锁，这与实际需要的功能不一致，故需要将waitTime设置为0
            if (getLock = lock.tryLock(0, 5, TimeUnit.SECONDS)) {
                logger.info("执行定时任务记录设备在线状态，执行时间：" + LocalDateTime.now());
                // 1、获取所有学校以及需要检测的设备的id集合
                MachineEntity machineEntity = new MachineEntity();
                machineEntity.setRequireCheck(1).setDeviceModel(Constants.THDID_AI06);
                List<MachineEntity> machineList = machineMapper.listMachine(machineEntity);
                List<Integer> requireCheckDeviceIdList = new ArrayList<>();
                for (MachineEntity machine : machineList) {
                    if (machine.getRequireCheck() == 1){
                        requireCheckDeviceIdList.add(Integer.valueOf(machine.getMachineId()));
                    }
                }
                List<com.alibaba.fastjson.JSONObject> schoolCodeList = schoolService.listSchool(null);
                JSONArray allDeviceList = new JSONArray();
                List<SchoolThdidUrlEntity> thdidUrlList = new ArrayList<>();
                // 2、获取所有后台所有学校的所有实义德的设备列表
                for (com.alibaba.fastjson.JSONObject school : schoolCodeList) {
                    Integer schoolCode = school.getInteger("schoolCode");
                    SchoolThdidUrlEntity thdidUrl = schoolService.getSchoolThdidUrlAndGroupInfo(schoolCode, Constants.THDID_AI06);
                    thdidUrlList.add(thdidUrl);
                }

                Set<SchoolThdidUrlEntity> removeRepeatThdidUrl = new HashSet<>(thdidUrlList);
                for (SchoolThdidUrlEntity thdidUrl : removeRepeatThdidUrl) {
                    JSONObject params = new JSONObject();
                    params.put("page", 1);
                    params.put("amount", Integer.MAX_VALUE);
                    JSONObject result;
                    try{
                        result = thDio.THD_interface(thdidUrl.getPathUrl(),"/device/sum_list", params, true, thdidUrl.getAccessToken());
                        if (result.getInt("code") == 0 && result.containsKey("data")){
                            JSONObject data = result.getJSONObject("data");
                            JSONArray deviceList = data.getJSONArray("list");
                            allDeviceList.addAll(deviceList);
                        }
                    }catch (Exception e){
                        logger.error("《{}》的后台连接失败，该后台的设备在线状态统计未完成！", thdidUrl);
                        continue;
                    }
                }
                List<DeviceEntity> deviceList = new ArrayList<>();
                for (Object machine : allDeviceList) {
                    DeviceEntity device = new DeviceEntity();
                    JSONObject jsonObject = (JSONObject)machine;
                    Boolean online = jsonObject.getBoolean("online");
                    device.setDeviceName(jsonObject.getString("device_name"))
                            .setDeviceId(jsonObject.getInt("device_id"))
                            .setDeviceSn(jsonObject.getString("device_sn"))
                            .setOnline(online ? 1 : 0);
                    deviceList.add(device);
                    // 设备不在线需要通知管理员
                    if (online == false && requireCheckDeviceIdList.contains(jsonObject.getInt("device_id"))){
                        String[] paramsWeiXin = { "",  "系统", "系统", new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date()), "设备=>" + jsonObject.getString("device_name") + "当前时间不在线，请注意！", ""};
                        // path参数为点击公众号消息后跳转的地址
                        logger.error("设备=>" + jsonObject.getString("device_name") + "当前时间不在线。");
                        PubCountEntity pubCountEntity = messageMapper.getPubCountOpenidByPhone("17628011691");
                        SendUtils.sendByWeixin(pubCountEntity, paramsWeiXin, pubCountEntity.getTemplateId());
                    }
                }
                // 3、存入设备状态
                int insertDeviceOnlineStatusResult = machineMapper.insertDeviceOnlineStatus(deviceList);
            }
            Thread.sleep(5000);//睡一会儿在关闭锁
        } catch (InterruptedException e) {
            logger.error("设备在线预警的时候获取锁异常",e);
        }finally {
            if (!getLock) {
                return;
            }
            lock.unlock();
        }
    }
}
